package com.lsq.tucao.user.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

/**
 * @Author linshouqiang
 * @Description JWT工具类
 * @Date 2020/11/25 10:25
 * @Version 1.0
 */
@Slf4j
@Component
public class JWTUtils {

    /**
     * 密钥
     */
    private static final String SECRET = "#@#@#@#ls%^%^q4568lov*&^eht*&%^$t";
    /**
     * 密钥过期期限（天）
     */
    private static final int EXPIRE = 1;

    /**
    * 生成token   header.payload.sign
    */
    public static String getToken(Map<String,String> map){
        log.info("开始生成token。。。");
        //设置token有效时间
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.DATE,EXPIRE);

        //创建jwt builder
        JWTCreator.Builder builder = JWT.create();

        //不设置header,header为默认值
        //payload
        map.forEach((k,v)->{
            builder.withClaim(k,v);
        });

        String token = builder
                //指定令牌过期时间
                .withExpiresAt(instance.getTime())
                //设置一个随机值，避免重放攻击
                .withJWTId(UUID.randomUUID().toString())
                //令牌的发布时间
                .withIssuedAt(new Date())
                //设置加密算法和密钥
                .sign(Algorithm.HMAC256(SECRET));

        log.info("token生成结束，token={}",token);
        return token;
    }

    /**
    * 验证token的合法性
    * 若不报异常，说明验证通过
    * 可能发生的异常类型：
    * 1、SignatureVerificationException   签名不一致异常
    * 2、TokenExpiredException            令牌过期异常
    * 3、AlgorithmMismatchException       算法不匹配异常
    * 4、InvalidClaimException            失效的payload异常
    */
    public static void verify(String token){
        JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);
    }

    /**
    * 获取token信息方法
    */
    public static DecodedJWT getTokenInfo(String token){
        DecodedJWT verify = JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);
//        String username = verify.getClaim("username").asString();
//        String password = verify.getClaim("password").asString();
        return verify;
    }

}
